package top.linyuxb.lycloud.admin.controller;

import jakarta.annotation.Resource;
import jakarta.persistence.criteria.Predicate;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import top.linyuxb.lycloud.admin.constant.StatusEnum;
import top.linyuxb.lycloud.admin.entity.*;
import top.linyuxb.lycloud.admin.repository.*;
import top.linyuxb.lycloud.admin.web.annotation.PermissionLimit;
import top.linyuxb.lycloud.admin.utils.ReturnT;
import top.linyuxb.lycloud.admin.service.impl.LoginService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Intellij IDEA.
 *
 * @Author: linyuxb
 * @Date: 2024/7/29 14:43
 * @Desc: 用户管理
 */
@Controller
@RequestMapping("/user")
public class UserController {

    @Resource
    private LyCloudUserRepository lyCloudUserRepository;
    @Resource
    private LyConfProjectRepository lyConfProjectRepository;
    @Resource
    private LyConfEnvRepository lyConfEnvRepository;

    @RequestMapping("")
    @PermissionLimit(adminuser = true)
    public String index(Model model) {
        List<LyConfProjectEntity> projectList = lyConfProjectRepository.findByStatusOrderByIdDesc(StatusEnum.VALID.getType());
        model.addAttribute("projectList", projectList);
        List<LyConfEnvEntity> envList = lyConfEnvRepository.findByStatusOrderByOrderDesc(StatusEnum.VALID.getType());
        model.addAttribute("envList", envList);
        return "user/user.index";
    }

    @RequestMapping("/pageList")
    @PermissionLimit(adminuser = true)
    @ResponseBody
    public Map<String, Object> pageList(@RequestParam(required = false, defaultValue = "0") int start,
                                        @RequestParam(required = false, defaultValue = "10") int length,
                                        String username,
                                        int permission) {
        Page<LyCloudUserEntity> all = lyCloudUserRepository.findAll(
                (root, criteriaQuery, cb) -> {
                    List<Predicate> predicates = new ArrayList<>();
                    if (StringUtils.isNotBlank(username)) {
                        predicates.add(cb.equal(root.get("username").as(String.class), username));
                    }
                    if (permission > -1) {
                        predicates.add(cb.equal(root.get("permission").as(Integer.class), permission));
                    }
                    return cb.and(predicates.toArray(new Predicate[0]));
                },
                PageRequest.of(
                        (start > 0 ? start / length : 0), length,
                        Sort.by(Sort.Direction.DESC, "id")
                )
        );
        List<LyCloudUserEntity> data = all.getContent();
        int list_count = (int) all.getTotalElements();

        // package result
        Map<String, Object> maps = new HashMap<>();
        maps.put("data", data);
        // 总记录数
        maps.put("recordsTotal", list_count);
        // 过滤后的总记录数
        maps.put("recordsFiltered", list_count);
        return maps;
    }

    /**
     * add
     *
     * @return
     */
    @RequestMapping("/add")
    @PermissionLimit(adminuser = true)
    @ResponseBody
    public ReturnT<String> add(LyCloudUserEntity lyCloudUser) {
        // valid
        if (StringUtils.isBlank(lyCloudUser.getUsername())) {
            return new ReturnT<>(ReturnT.FAIL.getCode(), "用户名不可为空");
        }
        if (StringUtils.isBlank(lyCloudUser.getPassword())) {
            return new ReturnT<>(ReturnT.FAIL.getCode(), "密码不可为空");
        }
        if (!(lyCloudUser.getPassword().length() >= 4 && lyCloudUser.getPassword().length() <= 100)) {
            return new ReturnT<>(ReturnT.FAIL.getCode(), "密码长度限制为4~50");
        }

        // passowrd md5
        String md5Password = DigestUtils.md5DigestAsHex(lyCloudUser.getPassword().getBytes());
        lyCloudUser.setPassword(md5Password);
        lyCloudUserRepository.save(lyCloudUser);
        return ReturnT.SUCCESS;
    }

    /**
     * delete
     *
     * @return
     */
    @RequestMapping("/delete")
    @PermissionLimit(adminuser = true)
    @ResponseBody
    public ReturnT<String> delete(HttpServletRequest request, String username) {
        LyCloudUserEntity loginUser = (LyCloudUserEntity) request.getAttribute(LoginService.LOGIN_IDENTITY);
        if (loginUser.getUsername().equals(username)) {
            return new ReturnT<>(ReturnT.FAIL.getCode(), "禁止操作当前登录账号");
        }

        lyCloudUserRepository.deleteByUsername(username);
        return ReturnT.SUCCESS;
    }

    /**
     * update
     *
     * @return
     */
    @RequestMapping("/update")
    @PermissionLimit(adminuser = true)
    @ResponseBody
    public ReturnT<String> update(HttpServletRequest request, LyCloudUserEntity lyCloudUser) {
        LyCloudUserEntity loginUser = (LyCloudUserEntity) request.getAttribute(LoginService.LOGIN_IDENTITY);
        if (loginUser.getUsername().equals(lyCloudUser.getUsername())) {
            return new ReturnT<>(ReturnT.FAIL.getCode(), "禁止操作当前登录账号");
        }
        // valid
        if (StringUtils.isBlank(lyCloudUser.getUsername())) {
            return new ReturnT<>(ReturnT.FAIL.getCode(), "用户名不可为空");
        }

        LyCloudUserEntity existUser = lyCloudUserRepository.findByUsername(lyCloudUser.getUsername());
        if (existUser == null) {
            return new ReturnT<>(ReturnT.FAIL.getCode(), "用户名非法");
        }

        if (StringUtils.isNotBlank(lyCloudUser.getPassword())) {
            if (!(lyCloudUser.getPassword().length() >= 4 && lyCloudUser.getPassword().length() <= 50)) {
                return new ReturnT<>(ReturnT.FAIL.getCode(), "密码长度限制为4~50");
            }
            // passowrd md5
            String md5Password = DigestUtils.md5DigestAsHex(lyCloudUser.getPassword().getBytes());
            existUser.setPassword(md5Password);
        }
        existUser.setPermission(lyCloudUser.getPermission());

        lyCloudUserRepository.save(existUser);
        return ReturnT.SUCCESS;
    }

    @RequestMapping("/updatePermissionData")
    @PermissionLimit(adminuser = true)
    @ResponseBody
    public ReturnT<String> updatePermissionData(
            String username, @RequestParam(required = false) String[] permissionData) {
        LyCloudUserEntity existUser = lyCloudUserRepository.findByUsername(username);
        if (existUser == null) {
            return new ReturnT<>(ReturnT.FAIL.getCode(), "参数非法");
        }
        String permissionDataArrStr = permissionData != null ? StringUtils.join(permissionData, ",") : "";
        existUser.setPermissionData(permissionDataArrStr);
        lyCloudUserRepository.save(existUser);

        return ReturnT.SUCCESS;
    }

    @RequestMapping("/updatePwd")
    @ResponseBody
    public ReturnT<String> updatePwd(HttpServletRequest request, String password) {
        // new password(md5)
        if (StringUtils.isBlank(password)) {
            return new ReturnT<>(ReturnT.FAIL.getCode(), "密码不可为空");
        }
        if (!(password.length() >= 4 && password.length() <= 100)) {
            return new ReturnT<>(ReturnT.FAIL.getCode(), "密码长度限制为4~50");
        }
        String md5Password = DigestUtils.md5DigestAsHex(password.getBytes());

        // update pwd
        LyCloudUserEntity loginUser = (LyCloudUserEntity) request.getAttribute(LoginService.LOGIN_IDENTITY);

        LyCloudUserEntity existUser = lyCloudUserRepository.findByUsername(loginUser.getUsername());
        existUser.setPassword(md5Password);
        lyCloudUserRepository.save(existUser);

        return ReturnT.SUCCESS;
    }

}
